#ifndef __GAME_H__
#define __GAME_H__

#include <iostream>
#include <vector>
#include <string>
#include "Player.h"
#include "Monster.h"
#include "Item.h"
#include "Terrain.h"
#include "Map.h"
#include "Class.h"

#include "Game_Config.h"


/**
 *  @file
 *  Class "Game". Core engine.
 */


/** 
 * Enum of the different states of the Game
 * 
 */
enum 
{
	GAME_STATE_QUIT,
	GAME_STATE_MAIN,
	GAME_STATE_NEW,
	GAME_STATE_LOAD,
	GAME_STATE_PLAY,
	GAME_STATE_SAVE,
	GAME_STATE_REST,
	GAME_STATE_MOVE,
	GAME_STATE_PRINTCHAR,
	GAME_STATE_EQUIPITEM,
	GAME_STATE_PRINTHELP
};



/** 
 * the Core class of the program
 * Loads all data
 * Interacts with the Player
 * 
 */
class Game
{
public:
	Game();
	~Game();
	void	printBanner();
	int		mainLoop();
	bool	load();
	void	generateCharater();
	void	reset();


private:
	std::vector<int>		m_vecMaxXPperLevel;		//!< Leveling information
	Player*					m_player;				//!< The Player class
	std::vector<Monster*>	m_monsters;				//!< All Monsters in the Game
	std::vector<Item*>		m_items;				//!< All Items in the Game
	std::vector<Terrain*>	m_terrains;				//!< All Terrains in the Game
	std::vector<Map*>		m_maps;					//!< All Maps in the Game
	std::vector<Class*>		m_classes;				//!< All Classes in the Game

	t_coord					m_playerCoord;			//!< Current Player Coordinate
	Map*					m_currentMap;			//!< Current Map

	int						m_iState;				//!< Current State of the Game

	void					printLocationInformation();
	void					processCellInfo(MapCell cell);
	bool					processCellEncounter(MapCell cell);
	bool					processCellMapChange(MapCell cell);

	void					printGameOver();
	void					GameOver();
	void					saveGame();
	void					loadGame();

	Monster*				newEncounter(std::string npc);
	char					printFightMenu(Monster* newMonster);
	bool					processFightMenu(char choice, Monster* newMonster);
	bool					processFight(Monster* newMonster);
	bool					processFlee(Monster* newMonster);

	void					printHelp();

	char					printMainMenu();
	void					processMainMenu(char choice);

	char					printGameMenu();
	void					processGameMenu(char choice);

	char					printMoveMenu();
	void					processMoveMenu(char choice);

	int						printEquipMenuItem();
	char					printEquipMenuPlace();
	void					processEquipMenu(char choicePlace, int choiceItem);

	void					loadLevelingInformation();
	void					showLevelingInformation();
	void					freeLevelingInformation();

	void					loadMonstersInformation();
	void					showMonstersInformation();
	void					freeMonstersInformation();

	void					loadItemsInformation();
	void					showItemsInformation();
	void					freeItemsInformation();

	void					loadItemsForMonsters();
	void					extractItemsForMonstersFromStruct(std::vector<s_ItemsForMonster*> itemList);
	void					freeItemsForMonstersStruct(std::vector<s_ItemsForMonster*> itemList);
	void					showItemsForMonsters();

	void					loadTerrainInformation();
	void					showTerrainInformation();
	void					freeTerrainInformation();

	void					loadMapInformation();
	void					showMapInformation();
	bool					checkMapInformation();

	void					loadClassInformation();
	void					showClassInformation();
	void					freeClassInformation();

};


#endif // __GAME_H__